﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Sicat.Aten.Localization.Test
{
    public static class ExcelReflectionUtil
    {

        public static object GetExcelApp()
        {
            return Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
        }

        public static Assembly GetExcelAssembly()
        {
            return Assembly.GetAssembly(Type.GetTypeFromProgID("Excel.Application"));
        }

        public static Type GetExcelType(string typeName)
        {
            string fullName = @"Microsoft.Office.Interop.Excel." + typeName;
            return GetExcelAssembly().GetType(fullName);
        }

        public static object GetEnum(string typeName, string value)
        {
            Type type = GetExcelType(typeName);
            object format = Enum.Parse(type, value);
            return format;
        }

        /// <summary>
        /// close the process by the given top-level window handle
        /// </summary>
        /// <param name="hWnd">a Long number indicating the top-level window handle of a window</param>
        public static void CloseProcess(object excelApp)
        {
            int hWnd = (int)(excelApp.GetType().InvokeMember("Hwnd", BindingFlags.Public | BindingFlags.GetProperty, null, excelApp, new object[0]));
            IntPtr processID = new IntPtr();
            GetWindowThreadProcessId(hWnd, ref processID);
            System.Diagnostics.Process process = System.Diagnostics.Process.GetProcessById(processID.ToInt32());
            process.Kill();
        }

        [System.Runtime.InteropServices.DllImport("user32.DLL")]
        private static extern IntPtr GetWindowThreadProcessId(int hWnd, ref IntPtr lpdwProcessID);


        public static object InvokeMethod(object instance, string methodName, params object[] parameters)
        {
            return instance.GetType().InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, instance, parameters);
        }

        public static object GetPropertyValue(object instance, string propName, params object[] index)
        {
            return instance.GetType().InvokeMember(propName, BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, instance,index);
        }

        public static void SetPropertyValue(object instance, string propName, object value, params object[] index)
        {
            List<object> parameters = new List<object>();
            foreach (object indexParam in index)
            {
                parameters.Add(indexParam);
            }
            parameters.Add(value);
            instance.GetType().InvokeMember(propName, BindingFlags.IgnoreCase | BindingFlags.SetProperty | BindingFlags.OptionalParamBinding, null, instance, parameters.ToArray());
        }

    }
}
